﻿// -
// <copyright file="RelayService.cs" company="Microsoft Corporation">
//    Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// -

using System;

namespace Hawaii.Services.Client.Relay
{
    /// <summary>
    /// Helper class that provides access to the Relay service.
    /// </summary>
    public static class RelayService
    {
        /// <summary>
        /// Specifies the service host name. This will be used to create the service url.
        /// </summary>
        public const string HostName = @"http://relay2.hawaii-services.net";

        /// <summary>
        /// Specifies a signature for the REST methods that manage endpoints.
        /// </summary>
        public const string EndPointSignature = "Endpoint";

        /// <summary>
        /// Specifies a signature for the REST methods that manage groups.
        /// </summary>
        public const string GroupSignature = "Group";

        /// <summary>
        /// Query string key for name.
        /// </summary>
        public const string NameKey = "name";

        /// <summary>
        /// Query string key for timeout.
        /// </summary>
        public const string TtlKey = "ttl";

        /// <summary>
        /// Query string key for to.
        /// </summary>
        public const string ToKey = "to";

        /// <summary>
        /// Query string key for filter.
        /// </summary>
        public const string FilterKey = "filter";

        /// <summary>
        /// Query string key for wait.
        /// </summary>
        public const string WaitKey = "wait";

        /// <summary>
        /// Helper method to initiate the call that creates an endpoint.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="name">Specifies a name of the client.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        public static void CreateEndPointAsync(
            string hawaiiAppId,
            string name,
            ServiceAgent<EndpointResult>.OnCompleteDelegate onComplete)
        {
            RelayService.CreateEndPointAsync(hawaiiAppId, name, onComplete, null);
        }

        /// <summary>
        /// Helper method to initiate the call that creates an endpoint.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="name">Specifies a name of the client.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        /// <param name="stateObject">Specifies a user-defined object.</param>
        public static void CreateEndPointAsync(
            string hawaiiAppId,
            string name,
            ServiceAgent<EndpointResult>.OnCompleteDelegate onComplete,
            object stateObject)
        {
            CreateEndPointAgent agent = new CreateEndPointAgent(
                RelayService.HostName,
                hawaiiAppId, 
                name, 
                TimeSpan.MaxValue);

            agent.ProcessRequest(onComplete);
        }

        /// <summary>
        /// Helper method to initiate the call that deletes an endpoint.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="endpoint">Specifies an endpoint.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        public static void DeleteEndPointAsync(
            string hawaiiAppId,
            Endpoint endpoint,
            ServiceAgent<EndpointResult>.OnCompleteDelegate onComplete)
        {
                RelayService.DeleteEndPointAsync(
                    hawaiiAppId, 
                    endpoint, 
                    onComplete, 
                    null);
        }

        /// <summary>
        /// Helper method to initiate the call that deletes an endpoint.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="endpoint">Specifies an endpoint.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        /// <param name="stateObject">Specifies a user-defined object.</param>
        public static void DeleteEndPointAsync(
            string hawaiiAppId,
            Endpoint endpoint,
            ServiceAgent<EndpointResult>.OnCompleteDelegate onComplete,
            object stateObject)
        {
            DeleteEndPointAgent agent = new DeleteEndPointAgent(
                RelayService.HostName,
                hawaiiAppId, 
                endpoint, 
                stateObject);

            agent.ProcessRequest(onComplete);
        }

        /// <summary>
        /// Helper method to initiate the call that will join an endpoint to a group.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="endpoint">Specifies an endpoint to join a group.</param>
        /// <param name="group">Specifies a target group.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        public static void JoinGroupAsync(
            string hawaiiAppId,
            Endpoint endpoint,
            Group group,
            ServiceAgent<GroupResult>.OnCompleteDelegate onComplete)
        {
                RelayService.JoinGroupAsync(
                    hawaiiAppId, 
                    endpoint, 
                    group, 
                    onComplete, 
                    null);
        }

        /// <summary>
        /// Helper method to initiate the call that will join an endpoint to a group.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="endpoint">Specifies an endpoint to join a group.</param>
        /// <param name="group">Specifies a target group.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        /// <param name="stateObject">Specifies a user-defined object.</param>
        public static void JoinGroupAsync(
            string hawaiiAppId,
            Endpoint endpoint,
            Group group,
            ServiceAgent<GroupResult>.OnCompleteDelegate onComplete,
            object stateObject)
        {
            JoinGroupAgent agent = new JoinGroupAgent(
                RelayService.HostName,
                hawaiiAppId, 
                endpoint, 
                group, 
                stateObject);

            agent.ProcessRequest(onComplete);
        }

        /// <summary>
        /// Helper method to initiate the call that will have an endpoint leave from a group.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="endpoint">Specifies an endpoint to leave a group.</param>
        /// <param name="group">Specifies a target group.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        public static void LeaveGroupAsync(
            string hawaiiAppId,
            Endpoint endpoint,
            Group group,
            ServiceAgent<GroupResult>.OnCompleteDelegate onComplete)
        {
            RelayService.LeaveGroupAsync(
                hawaiiAppId, 
                endpoint, 
                group, 
                onComplete, 
                null);
        }

        /// <summary>
        /// Helper method to initiate the call that will have an endpoint leave from a group.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="endpoint">Specifies an endpoint to leave a group.</param>
        /// <param name="group">Specifies a target group.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        /// <param name="stateObject">Specifies a user-defined object.</param>
        public static void LeaveGroupAsync(
            string hawaiiAppId,
            Endpoint endpoint,
            Group group,
            ServiceAgent<GroupResult>.OnCompleteDelegate onComplete,
            object stateObject)
        {
            LeaveGroupAgent agent = new LeaveGroupAgent(
                RelayService.HostName,
                hawaiiAppId, 
                endpoint, 
                group, 
                stateObject);

            agent.ProcessRequest(onComplete);
        }

        /// <summary>
        /// Helper method to initiate the call that will send a message.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="fromEndPoint">Specifies an from end point.</param>
        /// <param name="recipientIds">Specifies the recipients (either endpoint or group) ids.</param>
        /// <param name="message">Specifies an message data to be sent.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        public static void SendMessageAsync(
            string hawaiiAppId,
            Endpoint fromEndPoint,
            string recipientIds,
            byte[] message,
            ServiceAgent<MessagingResult>.OnCompleteDelegate onComplete)
        {
            RelayService.SendMessageAsync(hawaiiAppId, fromEndPoint, recipientIds, message, onComplete, null);
        }

        /// <summary>
        /// Helper method to initiate the call that will send a message.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="fromEndPoint">Specifies an from end point.</param>
        /// <param name="recipientIds">Specifies the recipients (either endpoint or group) ids.</param>
        /// <param name="message">Specifies an message data to be sent.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        /// <param name="stateObject">Specifies a user-defined object.</param>
        public static void SendMessageAsync(
            string hawaiiAppId,
            Endpoint fromEndPoint,
            string recipientIds,
            byte[] message,
            ServiceAgent<MessagingResult>.OnCompleteDelegate onComplete,
            object stateObject)
        {
            SendMessageAgent agent = new SendMessageAgent(
                RelayService.HostName,
                hawaiiAppId,
                fromEndPoint,
                recipientIds,
                message,
                TimeSpan.MaxValue,
                stateObject);
            agent.ProcessRequest(onComplete);
        }

        /// <summary>
        /// Helper method to initiate the call that will receive a message.
        /// </summary>
        /// <param name="hawaiiAppId">
        /// Specifies the Hawaii Application Id.
        /// </param>
        /// <param name="endpoint">
        /// Specifies an endpoint to leave a group.
        /// </param>
        /// <param name="filter">
        /// Specifies a list of registration ids for Endpoints and/or Groups that
        /// identify senders and/or group recipients of desired messages.
        /// </param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        public static void ReceiveMessagesAsync(
            string hawaiiAppId,
            Endpoint endpoint,
            string filter,
            ServiceAgent<MessagingResult>.OnCompleteDelegate onComplete)
        {
            RelayService.ReceiveMessagesAsync(
                hawaiiAppId, 
                endpoint, 
                filter, 
                onComplete, 
                null);
        }

        /// <summary>
        /// Helper method to initiate the call that will receive a message.
        /// </summary>
        /// <param name="hawaiiAppId">
        /// Specifies the Hawaii Application Id.
        /// </param>
        /// <param name="endpoint">
        /// Specifies an endpoint to leave a group.
        /// </param>
        /// <param name="filter">
        /// Specifies a list of registration ids for Endpoints and/or Groups that
        /// identify senders and/or group recipients of desired messages.
        /// </param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        /// <param name="stateObject">Specifies a user-defined object.</param>
        public static void ReceiveMessagesAsync(
            string hawaiiAppId,
            Endpoint endpoint,
            string filter,
            ServiceAgent<MessagingResult>.OnCompleteDelegate onComplete,
            object stateObject)
        {
            ReceiveMessagesAgent agent = new ReceiveMessagesAgent(
                RelayService.HostName,
                hawaiiAppId, 
                endpoint, 
                filter,
                TimeSpan.Zero, // Default to return immediately
                stateObject);

            agent.ProcessRequest(onComplete);
        }

        /// <summary>
        /// Helper method to initiate the call that creates a new group.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        public static void CreateGroupAsync(
            string hawaiiAppId,
            ServiceAgent<GroupResult>.OnCompleteDelegate onComplete)
        {
            RelayService.CreateGroupAsync(hawaiiAppId, onComplete, null);
        }

        /// <summary>
        /// Helper method to initiate the call that creates a new group.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        /// <param name="stateObject">Specifies a user-defined object.</param>
        public static void CreateGroupAsync(
            string hawaiiAppId,
            ServiceAgent<GroupResult>.OnCompleteDelegate onComplete,
            object stateObject)
        {
            CreateGroupAgent agent = new CreateGroupAgent(
                RelayService.HostName,
                hawaiiAppId,
                TimeSpan.MaxValue,
                stateObject);
            agent.ProcessRequest(onComplete);
        }

        /// <summary>
        /// Helper method to initiate the call that deletes a group.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="group">Specifies a group to be deleted.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        public static void DeleteGroupAsync(
            string hawaiiAppId,
            Group group,
            ServiceAgent<GroupResult>.OnCompleteDelegate onComplete)
        {
            RelayService.DeleteGroupAsync(hawaiiAppId, group, onComplete, null);
        }

        /// <summary>
        /// Helper method to initiate the call that deletes a group.
        /// </summary>
        /// <param name="hawaiiAppId">Specifies the Hawaii Application Id.</param>
        /// <param name="group">Specifies a group to be deleted.</param>
        /// <param name="onComplete">Specifies an "on complete" delegate callback.</param>
        /// <param name="stateObject">Specifies a user-defined object.</param>
        public static void DeleteGroupAsync(
            string hawaiiAppId,
            Group group,
            ServiceAgent<GroupResult>.OnCompleteDelegate onComplete,
            object stateObject)
        {
            DeleteGroupAgent agent = new DeleteGroupAgent(
                RelayService.HostName,
                hawaiiAppId, 
                group, 
                stateObject);

            agent.ProcessRequest(onComplete);
        }
    }
}
